﻿#include "ExperimentOperation.h"

/**
 * @brief 构造函数
 */
ExperimentOperation::ExperimentOperation()
{
}

/**
 * @brief 析构函数
 */
ExperimentOperation::~ExperimentOperation()
{}

/**启动实验
 * @brief ExperimentOperation:: startExperiment
 */
Q_INVOKABLE  void ExperimentOperation:: startExperiment()
{
    __LOG_FSTART__;
    udpClient=UdpClient::getInstance();
    cpsUdpClient=CpsUdpClient::getInstance();

    StaticProperties::expSendList.clear();
    StaticProperties::expStartStepList.clear();
    StaticProperties::totalExpTime=0;

    switch (StaticProperties::currentExpType)
    {
    case 0:
        StaticProperties::currentExpModule=1;
        ExpCommonMethod::Common().analysisTotalProcessExp(StaticProperties::currentExpName);
        break;
    case 1:
        StaticProperties::currentExpModule=1;
        ExpCommonMethod::Common().analysisReleasseTargetExp(StaticProperties::currentExpName);
        break;
    case 2:
        StaticProperties::currentExpModule=2;
        ExpCommonMethod::Common().analysisPracticeTargetExp(StaticProperties::currentExpName);
        break;
    case 3:
        StaticProperties::currentExpModule=3;
        ExpCommonMethod::Common().analysisShiftingTargetExp(StaticProperties::currentExpName);
        break;
    case 4:
        StaticProperties::currentExpModule=4;
        ExpCommonMethod::Common().analysisPurifyingExp(StaticProperties::currentExpName);
        break;
    }

    StaticProperties::expStartStep=1;
    if((StaticProperties::currentExpType==0 && StaticProperties::softType==0) || StaticProperties::currentExpType==4)
    {
        QSqlDatabase db = dbHelper::openConnection();
        QSqlQuery query(db);
        QString expName;
        if(StaticProperties::currentExpType==0){
            expName=QString("value_1=(Select PurifyingExp From MainExperimentalProcess Where ExperimentName='%1')").arg(StaticProperties::currentExpName);
        }
        else{
            expName=QString("value_1='%1'").arg(StaticProperties::currentExpName);
        }
        QString sql=QString("Select count(*) num From exe_config "
                            "Where id=(Select id From exe_config Where type=0 and %1) and type=3").arg(expName);

        query.exec(sql);
        int num=0;
        while (query.next()) {
            num=query.value("num").toInt();
        }
        if(num>0){
            udpClient->ClientSendingData(CommonHelper::Common().GetSendData( CommCommand::I().getTurntablePosition()));
            return;
        }
    }

    udpClient->ClientSendingData(CommonHelper::Common().GetSendData( CommCommand::I().startExperiment()));
    cpsUdpClient->ClientSendingData(CommonHelper::Common().GetSendData( CommCommand::I().startExperiment()));
    ExpCommonMethod::Common().saveExpInfo();

    __LOG_FEND__;
}

/** 实验相关操作
 * @brief ExperimentOperation::operationExperiment
 * @param 2停止 3暂停  4继续 5复位 6急停(暂时没有)
 */
Q_INVOKABLE void ExperimentOperation::operationExperiment(int order)
{
    __LOG_FSTART(order);
    udpClient=UdpClient::getInstance();
    cpsUdpClient=CpsUdpClient::getInstance();
    if(order==2)//停止
    {
        udpClient->ClientSendingData(CommonHelper::Common().GetSendData( CommCommand::I().stopExperiment()));
        cpsUdpClient->ClientSendingData(CommonHelper::Common().GetSendData( CommCommand::I().stopExperiment()));
    }
    else if(order==3)//暂停
    {
        StaticProperties::expStatus=2;
        if(!StaticProperties::isWait){
            udpClient->ClientSendingData(CommonHelper::Common().GetSendData( CommCommand::I().pauseExperiment()));
        }
        else{
            QMLSignal::I().experimentStatus(3,1,"");
        }
    }
    else if(order==4)//继续
    {
        if(StaticProperties::expStatus==2)
        {
            StaticProperties::expStatus=1;
            if(!StaticProperties::isWait){
                udpClient->ClientSendingData(CommonHelper::Common().GetSendData( CommCommand::I().continueExperiment()));
            }
            else{
                QMLSignal::I().experimentStatus(4,1,"");
            }
        }
        else
        {
            StaticProperties::expStep++;
            QMLSignal::I().experimentStatus(4,1,"");
            ExperimentThread::I().run();
        }
    }
    else if(order==6)//急停
    {
        StaticProperties::expStatus=0;
    }

    __LOG_FEND__;
    return;
}

/** 单步执行操作
 * @brief ExperimentOperation::stepOperatingSimulation
 * @param 模块
 * @param 类型
 * @param 操作信息
 */
Q_INVOKABLE void ExperimentOperation::stepOperatingSimulation(QString module,QString type,QList<QString> operation)
{

    qDebug() << "stepOperatingSimulation" << module << type << operation;
    __LOG_FSTART(module+" "+type+" "+operation.join(" "));

    udpClient=UdpClient::getInstance();

    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);

    if(module=="1" || module=="3")//放靶或转靶
    {
        QString sql=QString("Update ModuleResetStatus set Status=0 Where module='1'");
        query.exec(sql);
        if(StaticProperties::runningList.contains("10"))
        {
            QMLSignal::I().emitSendResetMsg("1",10);
            return;
        }
        if(type=="1")//挡板
        {
            udpClient->ClientSendingData(CommonHelper::Common().GetSendData(CommCommand::I().getBarrier(QString::number(1),operation[0])));
        }
        else if(type=="2")//取靶
        {
            if(operation.length()>2){
                udpClient->ClientSendingData(CommonHelper::Common().GetSendData(CommCommand::I().getAcquisitionTarget(QString::number(1),operation[0],operation[1],operation[2])));
            }
            else{
                udpClient->ClientSendingData(CommonHelper::Common().GetSendData(CommCommand::I().getAcquisitionTarget(QString::number(1),operation[0],operation[1],"")));

            }
        }
        else if(type=="3")//夹爪
        {
            udpClient->ClientSendingData(CommonHelper::Common().GetSendData(CommCommand::I().getClampingJaw(QString::number(1),operation[0])));
        }
        else if(type=="4")//开盖
        {
            udpClient->ClientSendingData(CommonHelper::Common().GetSendData(CommCommand::I().getOpenTheLid(QString::number(1),operation[0])));
        }
        else if(type=="5")//加速端回靶
        {
            udpClient->ClientSendingData(CommonHelper::Common().GetSendData(CommCommand::I().getTransmissionTarget(module.toInt(),QString::number(1),operation[0])));
        }
        else if(type=="6")//转液
        {
            udpClient->ClientSendingData(CommonHelper::Common().GetSendData(CommCommand::I().getFluidTransfer(module.toInt(),QString::number(1),operation[0],operation[1],operation[2])));
        }
        else if(type=="10")//活检
        {
            QSqlDatabase db = dbHelper::openConnection();
            QSqlQuery query(db);
            QString sql="Select IsUsed From ComponentInfo Where module='3' and Serial='8'";
            query.exec(sql);

            int isUsed=1;

            while (query.next()) {
                isUsed=query.value("IsUsed").toInt();
            }
            if(isUsed==0){
                return;
            }
            udpClient->ClientSendingData(CommonHelper::Common().GetSendData(CommCommand::I().getActivityTesting(QString::number(1),operation[0])));
        }
        else if(type=="11")//旋盖夹爪
        {
            udpClient->ClientSendingData(CommonHelper::Common().GetSendData(CommCommand::I().rotaryCapClamp(QString::number(1),operation[0],operation[1])));
        }
    }
    else if(module=="2")
    {
        QString sql=QString("Update ModuleResetStatus set Status=0 Where module='2'");
        query.exec(sql);

        if(StaticProperties::runningList.contains("11"))
        {
            QMLSignal::I().emitSendResetMsg("1",11);
            return;
        }
        if(type=="1")//吸取梭体
        {
            udpClient->ClientSendingData(CommonHelper::Common().GetSendData(CommCommand::I().getSuctionTarget(QString::number(1),operation[0])));
        }
        else if(type=="2")//冷却
        {
            udpClient->ClientSendingData(CommonHelper::Common().GetSendData(CommCommand::I().getCooling(QString::number(1),operation[0],operation[1])));
        }
        else if(type=="3")//干燥
        {
            udpClient->ClientSendingData(CommonHelper::Common().GetSendData(CommCommand::I().getDry(QString::number(1),operation[0])));
        }
        else if(type=="4")//锁体组合运行
        {
            udpClient->ClientSendingData(CommonHelper::Common().GetSendData(CommCommand::I().getMoveTarget(QString::number(1),operation[0])));
        }
        else if(type=="5")//抱闸状态
        {
            udpClient->ClientSendingData(CommonHelper::Common().GetSendData(CommCommand::I().getLockedUp(QString::number(1),operation[0])));
        }
        else if(type=="6")//进料
        {
            udpClient->ClientSendingData(CommonHelper::Common().GetSendData(CommCommand::I().getFeed(QString::number(1),operation[0])));
        }
        else if(type=="7")//加速端回靶
        {
            udpClient->ClientSendingData(CommonHelper::Common().GetSendData(CommCommand::I().getTransmissionTarget(module.toInt(),QString::number(1),operation[0])));
        }
    }
    else if(module=="4"){
        QString sql=QString("Update ModuleResetStatus set Status=0 Where module='4'");
        query.exec(sql);

        if(type=="1")//注射器
        {
            if(StaticProperties::runningList.contains(operation[1]))
            {
                QMLSignal::I().emitSendSyringRunMsg("1",operation[1]);
                return;
            }

            QString code= CommonHelper::Common().getItemCode("3",operation[0]);

            QSqlDatabase db = dbHelper::openConnection();
            QSqlQuery query(db);

            QString sql=QString("Select Count(*) Num From SyringeMaintenance Where ConsumablesTypes='%1' and id='%2'").arg(code,operation[1]);
            query.exec(sql);
            int Num = 0;
            while (query.next()) {
                Num=query.value("Num").toInt();
            }
            if(Num>0){
                StaticProperties::runningList.append(operation[1]);

                sql=QString("Select InsideDiameter,ReductionRatio,ScrewLead,CircleStep From SyringeMaintenance Where ConsumablesTypes='%1' and id='%2'").arg(code,operation[1]);
                query.exec(sql);
                double InsideDiameter=0,ScrewLead=0,CircleStep = 0;
                QString ReductionRatio;
                while (query.next()) {
                    InsideDiameter=query.value("InsideDiameter").toDouble();
                    ReductionRatio=query.value("ReductionRatio").toString();
                    ScrewLead=query.value("ScrewLead").toDouble();
                    CircleStep=query.value("CircleStep").toDouble();
                }
                double speed=operation[8].toDouble();
                if(operation[9]=="mL/Min")// 速度单位:ml/分
                {
                    speed=CommonHelper::Common().minToSecond(QString::number(speed),QString::number(InsideDiameter)).toDouble();
                }
                QStringList reList=ReductionRatio.split(':');
                double stepNum=operation[6].toDouble()/ScrewLead*CircleStep*reList[1].toDouble();
                double time=operation[6].toDouble()/speed;
                double stepNumber= stepNum/time;

                udpClient->ClientSendingData(CommonHelper::Common().GetSendData(CommCommand::I().getSyring(operation[1],operation[1],operation[4],QString::number(stepNumber),QString::number(stepNum))));
            }
            else{
                QMLSignal::I().emitSyringDataLack();
            }
        }
        else if(type=="2")//阀门
        {
            udpClient->ClientSendingData(CommonHelper::Common().GetSendData(CommCommand::I().getValve(QString::number(8),operation[0],operation[1])));
        }
        else if(type=="3")//转盘
        {
            QSqlDatabase db = dbHelper::openConnection();
            QSqlQuery query(db);
            QString sql="Select IsUsed From ComponentInfo Where module='4' and Serial='6'";
            query.exec(sql);

            int isUsed;

            while (query.next()) {
                isUsed=query.value("IsUsed").toInt();
            }
            if(isUsed==0){
                return;
            }
            udpClient->ClientSendingData(CommonHelper::Common().GetSendData(CommCommand::I().getTurntable("7",operation[0])));
        }
        else if(type=="4")//盖盖
        {
            QSqlDatabase db = dbHelper::openConnection();
            QSqlQuery query(db);
            QString sql="Select IsUsed From ComponentInfo Where module='4' and Serial='7'";
            query.exec(sql);

            int isUsed;

            while (query.next()) {
                isUsed=query.value("IsUsed").toInt();
            }
            if(isUsed==0){
                return;
            }
            if(operation[0]=="是" )
            {
                udpClient->ClientSendingData(CommonHelper::Common().GetSendData(CommCommand::I().coverTheLid(QString::number(8))));
            }
        }
        else if(type=="6")//转液
        {
            QSqlDatabase db = dbHelper::openConnection();
            QSqlQuery query(db);
            QString sql="Select IsUsed From ComponentInfo Where module='4' and Serial='8'";
            query.exec(sql);

            int isUsed;

            while (query.next()) {
                isUsed=query.value("IsUsed").toInt();
            }
            if(isUsed==0){
                return;
            }
            udpClient->ClientSendingData(CommonHelper::Common().GetSendData(CommCommand::I().getFluidTransfer(module.toInt(),QString::number(1),operation[0],operation[1],operation[2])));
        }
        else if(type=="11")//加热
        {
            QSqlDatabase db = dbHelper::openConnection();
            QSqlQuery query(db);
            QString sql="Select IsUsed From ComponentInfo Where module='4' and Serial='9'";
            query.exec(sql);

            int isUsed;

            while (query.next()) {
                isUsed=query.value("IsUsed").toInt();
            }
            if(isUsed==0){
                return;
            }
            udpClient->ClientSendingData(CommonHelper::Common().GetSendData(CommCommand::I().getHeating(QString::number(1),operation[0],operation[1])));
        }
    }
    __LOG_FEND__;
}

/** 强制停止
 * @brief forcedStop
 */
Q_INVOKABLE void ExperimentOperation::forcedStop(){
    StaticProperties::isForcedStop=true;
    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);

    QString sql="Delete From ExperimentDetail";
    query.exec(sql);
    sql="Delete From ExperimentInfo";
    query.exec(sql);
    StaticProperties::expStatus=0;
    QMLSignal::I().experimentStatus(2,1,"");
}

/** 实验前校验启动条件
 * @brief checkExpRunningRule
 * @return 校验结果,空为可以启动实验
 */
Q_INVOKABLE QString ExperimentOperation::checkExpRunningRule()
{
    return ExpCommonMethod::Common().checkExpRunningRule();
}

/** 校验耗材注射器信息
 * @brief checkConsumablesSyring
 * @param 耗材名称
 * @return
 */
Q_INVOKABLE QString ExperimentOperation::checkConsumablesSyring(QString name)
{
    __LOG_FSTART__;
    return ExpCommonMethod::Common().checkConsumablesSyring(name);
    __LOG_FEND("SUCCEED");
}

/** 实验恢复继续实验
 * @brief
 * @param 类别 -1不继续
 */
Q_INVOKABLE void ExperimentOperation::continueExperiment(int type,int resetUnion)
{
    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);

    if(type==-1)//不继续0
    {
        QString sql="Delete From ExperimentDetail";
        query.exec(sql);
        sql="Delete From ExperimentInfo";
        query.exec(sql);
    }
    else{
        StaticProperties::expSendList.clear();
        QString sql="Select * From ExperimentDetail Where step<500";
        query.exec(sql);
        while (query.next())
        {
            QVariantMap map;
            map["Type"]=query.value("Type").toString();
            map["Module"]=query.value("Module").toString();
            map["Step"]=query.value("Step").toString();
            map["Info"]=query.value("Info").toString();
            StaticProperties::expSendList.insert(query.value("Key").toInt(),map);
        }

        StaticProperties::expConcurrencySendList.clear();
        sql="Select * From ExperimentDetail Where step>500";
        query.exec(sql);
        while (query.next())
        {
            QVariantMap map;
            map["Type"]=query.value("Type").toString();
            map["Module"]=query.value("Module").toString();
            map["Step"]=QString::number(query.value("Step").toInt()-500);
            map["Info"]=query.value("Info").toString();
            map["UnionId"]=query.value("UnionId").toString();
            StaticProperties::expConcurrencySendList.insert(query.value("Key").toInt(),map);
        }


        sql="Select * From ExperimentInfo";
        query.exec(sql);
        while (query.next())
        {
            StaticProperties::currentExpType=query.value("ExpModule").toInt();
            StaticProperties::currentExpName=query.value("ExpName").toString();
            StaticProperties::expStep=query.value("ExpStep").toInt();
        }

        if(StaticProperties::currentExpType==0 ||StaticProperties::currentExpType==1){
            //放靶日志
            sql="Select * From ReportDetail Where Module='1' and ReportSerial=(Select max(ReportSerial) From ReportDetail)";
            query.exec(sql);
            StaticProperties::expLogList[0].clear();
            while (query.next())
            {
                QVariantMap map;
                map["FinishTime"]=query.value("FinishTime").toString();
                map["Step"]=query.value("Step").toString();
                map["ActionInfo"]=query.value("ActionInfo").toString();
                map["Time"]=query.value("Time").toString();
                map["Status"]=query.value("Status").toString();
                StaticProperties::expLogList[0].insert(query.value("Step").toInt(),map);//放靶实验日志
            }
        }
        if(StaticProperties::currentExpType==0 ||StaticProperties::currentExpType==2){
            //打靶日志
            sql="Select * From ReportDetail Where Module='2' and ReportSerial=(Select max(ReportSerial) From ReportDetail)";
            query.exec(sql);
            StaticProperties::expLogList[1].clear();
            while (query.next())
            {
                QVariantMap map;
                map["FinishTime"]=query.value("FinishTime").toString();
                map["Step"]=query.value("Step").toString();
                map["ActionInfo"]=query.value("ActionInfo").toString();
                map["Time"]=query.value("Time").toString();
                map["Status"]=query.value("Status").toString();
                StaticProperties::expLogList[1].insert(query.value("Step").toInt(),map);
            }
        }
        if(StaticProperties::currentExpType==0 ||StaticProperties::currentExpType==3){
            //转靶日志
            sql="Select * From ReportDetail Where Module='3' and ReportSerial=(Select max(ReportSerial) From ReportDetail)";
            query.exec(sql);
            StaticProperties::expLogList[2].clear();
            while (query.next())
            {
                QVariantMap map;
                map["FinishTime"]=query.value("FinishTime").toString();
                map["Step"]=query.value("Step").toString();
                map["ActionInfo"]=query.value("ActionInfo").toString();
                map["Time"]=query.value("Time").toString();
                map["Status"]=query.value("Status").toString();
                StaticProperties::expLogList[2].insert(query.value("Step").toInt(),map);//放靶实验日志
            }
        }
        if((StaticProperties::currentExpType==0 && StaticProperties::softType==0) ||StaticProperties::currentExpType==4){
            //纯化日志
            sql="Select * From ReportDetail Where Module='4' and step not like '并发%' and ReportSerial=(Select max(ReportSerial) From ReportDetail)";
            query.exec(sql);
            StaticProperties::expLogList[3].clear();
            while (query.next())
            {
                QVariantMap map;
                map["FinishTime"]=query.value("FinishTime").toString();
                map["Step"]=query.value("Step").toString();
                map["ActionInfo"]=query.value("ActionInfo").toString();
                map["Time"]=query.value("Time").toString();
                map["Status"]=query.value("Status").toString();
                StaticProperties::expLogList[3].insert(query.value("Step").toInt(),map);//放靶实验日志
            }

            sql="Select * From ReportDetail Where Module='4' and step like '并发%' and ReportSerial=(Select max(ReportSerial) From ReportDetail)";
            query.exec(sql);
            StaticProperties::expConcurrencyLogList.clear();
            while (query.next())
            {
                QVariantMap map;
                map["FinishTime"]=query.value("FinishTime").toString();
                map["Step"]=query.value("Step").toString();
                map["ActionInfo"]=query.value("ActionInfo").toString();
                map["Time"]=query.value("Time").toString();
                map["Status"]=query.value("Status").toString();
                StaticProperties::expConcurrencyLogList.insert(query.value("Step").toString().remove("并发").toInt(),map);//放靶实验日志
            }
            qDebug()<<StaticProperties::expConcurrencyLogList;
        }

        StaticProperties::maxStep=StaticProperties::expSendList.lastKey();

        if(type==0)//重新执行当前步骤
        {
            StaticProperties::currentExpModule=StaticProperties::continueModule[0];
        }
        else if(type==1)//执行下一步
        {
            StaticProperties::currentExpModule=StaticProperties::continueModule[1];
            StaticProperties::expStep++;
        }

        StaticProperties::expRecovery=true;
        QMLSignal::I().experimentStatus(1,1,"");
        QMLSignal::I().emitModuleCurrent(StaticProperties::currentExpModule);
        StaticProperties::expStatus=1;
        ExperimentThread::I().setExpInfo();


        if(resetUnion==1 && StaticProperties::isConcurrency){
            ExperimentThread::I().concurrencyUnionRun();
        }
        ExperimentThread::I().run();
    }
}

/** 保存浓度
 * @brief ExperimentOperation::SaveConc
 * @param conc
 */
Q_INVOKABLE void ExperimentOperation::SaveConc(QString conc)
{
    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);
    QString serial;
    QString sql="Select max(Serial) as Serial From ReportInfo";
    query.exec(sql);
    while (query.next()) {
        serial=query.value("Serial").toString().isNull()?"1":query.value("Serial").toString();
    }
    sql=QString("Update ReportInfo Set Conc='%1' Where Serial='%2'").arg(conc,serial);
    query.exec(sql);
}

/** 故障继续实验
 * @brief ExperimentOperation::errorContinueExp
 * @param type
 * @param step
 */
Q_INVOKABLE bool ExperimentOperation::errorContinueExp(int type,int step,int resetUnion){

    __LOG_FSTART("type"+QString::number(type)+" step:"+QString::number(type));
    StaticProperties::expStatus=1;
    if(resetUnion==1 && StaticProperties::isConcurrency){
        if(type==0)
        {
            ExperimentThread::I().concurrencyUnionRun();
        }
        else if(type==1){
            StaticProperties::expUnionStep++;
            ExperimentThread::I().concurrencyUnionRun();
        }
    }
    else if(resetUnion!=1)
    {
        if(type==0)
        {
            ExperimentThread::I().run();
        }
        else if(type==1){
            StaticProperties::expStep++;
            ExperimentThread::I().run();
        }
        else{
            if(step<1 || step>StaticProperties::maxStep){
                return false;
            }
            StaticProperties::expStep=step;
            StaticProperties::expStartStep=StaticProperties::expStep;
            ExperimentThread::I().run();
        }
    }


    return true;
}
